#include <mutex>

#include "field_type.h"

namespace Elements
{

FieldType::FieldType(const FieldType& other)
    : Element(other)
    , m_itemTypeId(other.m_itemTypeId)
    , m_caption(other.m_caption)
    , m_description(other.m_description)
    , m_valueType(other.m_valueType)
    , m_isBoardVisible(other.m_isBoardVisible)
{
}

bool FieldType::isSame(Element* const other) const
{
    const auto otherElement = dynamic_cast<FieldType const*>(other);
    if (nullptr == otherElement)
        return false;

    return bool(
        m_id == otherElement->m_id
        && m_itemTypeId == otherElement->m_itemTypeId
        && m_caption == otherElement->m_caption
        && m_description == otherElement->m_description
        && m_valueType == otherElement->m_valueType
        && m_isBoardVisible == otherElement->m_isBoardVisible
    );
}

Common::Json FieldType::toJson() const
{
    std::shared_lock locker(m_lock);
    Common::Json result;
    result["id"] = m_id;
    result["elementType"] = unsigned(elementType());
    result["itemTypeId"] = m_itemTypeId;
    result["caption"] = m_caption;
    result["description"] = m_description;
    result["valueType"] = unsigned(m_valueType);
    result["isBoardVisible"] = m_isBoardVisible;
    return result;
}

void FieldType::fromJson(const Common::Json& json)
{
    std::shared_lock locker(m_lock);
    m_id = json["id"].get<unsigned>();
    m_itemTypeId = json["itemTypeId"].get<unsigned>();
    m_caption = json["caption"].get<std::string>();
    m_description = json["description"].get<std::string>();
    m_valueType = FieldType::ValueType(json["valueType"].get<unsigned>());
    m_isBoardVisible = json["isBoardVisible"].get<bool>();
}

Element* FieldType::clone() const
{
    return new FieldType(*this);
}

ElementType FieldType::elementType() const
{
    return ElementType::FieldType;
}

unsigned FieldType::itemTypeId() const
{
    std::shared_lock locker(m_lock);
    return m_itemTypeId;
}

void FieldType::setItemTypeId(const unsigned value)
{
    std::unique_lock locker(m_lock);
    m_itemTypeId = value;
}

std::string FieldType::caption() const
{
    std::shared_lock locker(m_lock);
    return m_caption;
}

void FieldType::setCaption(const std::string& value)
{
    std::unique_lock locker(m_lock);
    m_caption = value;
}

std::string FieldType::description() const
{
    std::shared_lock locker(m_lock);
    return m_description;
}

void FieldType::setDescription(const std::string& value)
{
    std::unique_lock locker(m_lock);
    m_description = value;
}

FieldType::ValueType FieldType::valueType() const
{
    std::shared_lock locker(m_lock);
    return m_valueType;
}

void FieldType::setValueType(const FieldType::ValueType value)
{
    std::unique_lock locker(m_lock);
    m_valueType = value;
}

bool FieldType::isBoardVisible() const
{
    std::shared_lock locker(m_lock);
    return m_isBoardVisible;
}

void FieldType::setIsBoardVisible(const bool value)
{
    std::unique_lock locker(m_lock);
    m_isBoardVisible = value;
}

} // namespace Elements
